/*
 * GebruikerDAO.java
 *
 * Created on 24 februari 2008, 20:04
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package server.dataaccess;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;
import data.Gebruiker;
import data.Score;

/**
 *
 * @author Administrator
 */
public class GebruikerDAO {
    
    private static Logger logger = Logger.getLogger(GebruikerDAO.class);
    
    private static ResourceBundle bundle = ResourceBundle.getBundle("server.dataaccess.database");
    
    /** Creates a new instance of GebruikerDAO */
    private GebruikerDAO() {
        
    }
    
    public static boolean voegGebruikerToe(Gebruiker g){
        //Transactie starten waarbij eerst een score rij wordt toegevoegd met nullen
        //en vervolgens het gebruiker record zelf dat zal verwijzen naar dit score ID.
        
        String opdracht = "{call insertGebruiker(?,?,?,?,?,?,?,?,?,?,?)}";
        boolean gelukt = false;
        
        try{
            Connection conn = Database.getInstance().getConnection();
            try {
                conn.setAutoCommit(false);
                
                //Score toevoegen
                Score s = new Score();
                int scoreId = ScoreDAO.voegScoreToe(s,conn);
                
                
                //Gebruiker toevoegen
                CallableStatement cstmt = conn.prepareCall(opdracht);
                cstmt.setString(1,g.getNickname());
                cstmt.setString(2,g.getPaswoord());
                cstmt.setString(3,g.getEmail());
                cstmt.setDate(4,new java.sql.Date(g.getGeboortedatum().getTime()));
                cstmt.setString(5,g.getGeslacht());
                cstmt.setString(6,g.getHobbys());
                cstmt.setString(7,g.getExtra());
                cstmt.setString(8,g.getAvatar());
                cstmt.setBoolean(9,g.isOnline());
                cstmt.setBoolean(10,g.isGaming());
                cstmt.setInt(11,scoreId);
                
                cstmt.executeUpdate();
                cstmt.close();
                
                conn.commit();
                gelukt = true;
                
                logger.info("Gebruiker " + g.getNickname() + " toevoegen gelukt!");
                
            } catch (SQLException ex) {
                gelukt = false;
                conn.rollback();
                logger.error("Fout bij het toevoegen van een gebruiker!");
                logger.error(ex.getMessage());
            } finally{
                conn.setAutoCommit(true);
                conn.close();
            }
        }catch(SQLException ex){
            logger.error("Fout bij het openen of sluiten van de databaseconnectie tijdens het toevoegen van een gebruiker!");
            logger.error(ex.getMessage());
        }
        
        
        return gelukt;
    }
    
    public static boolean alleGebruikersOffline(){
        
        String opdracht = "{call alleGebruikersOffline()}";
        boolean gelukt = false;
        
        try{
            Connection conn = Database.getInstance().getConnection();
            try {

                //Gebruiker updaten
                CallableStatement cstmt = conn.prepareCall(opdracht);
                cstmt.executeUpdate();
                cstmt.close();
                
                gelukt = true;
                
                logger.info("Alle gebruikers op offline ingesteld!");
                
            } catch (SQLException ex) {
                gelukt = false;
                logger.error("Fout bij het instellen van alle gebruikers op offline!");
                logger.error(ex.getMessage());
            } finally{
                conn.close();
            }
        }catch(SQLException ex){
            logger.error("Fout bij het openen of sluiten van de databaseconnectie tijdens het offline zetten van alle gebruikers!");
            logger.error(ex.getMessage());
        }
        
        
        return gelukt;
    }
    
    public static boolean updateGebruiker(Gebruiker g){
        
        String opdracht = "{call updateGebruiker(?,?,?,?,?,?,?,?,?,?,?)}";
        boolean gelukt = false;
        
        try{
            Connection conn = Database.getInstance().getConnection();
            try {

                //Gebruiker updaten
                CallableStatement cstmt = conn.prepareCall(opdracht);
                cstmt.setString(1,g.getNickname());
                cstmt.setString(2,g.getPaswoord());
                cstmt.setString(3,g.getEmail());
                cstmt.setDate(4,new java.sql.Date(g.getGeboortedatum().getTime()));
                cstmt.setString(5,g.getGeslacht());
                cstmt.setString(6,g.getHobbys());
                cstmt.setString(7,g.getExtra());
                cstmt.setString(8,g.getAvatar());
                cstmt.setBoolean(9,g.isOnline());
                cstmt.setBoolean(10,g.isGaming());
                cstmt.setInt(11,g.getScoreId());
                
                cstmt.executeUpdate();
                cstmt.close();
                
                gelukt = true;
                
                logger.info("Gebruiker " + g.getNickname() + " updaten gelukt!");
                
            } catch (SQLException ex) {
                gelukt = false;
                logger.error("Fout bij het updaten van een gebruiker!");
                logger.error(ex.getMessage());
            } finally{
                conn.close();
            }
        }catch(SQLException ex){
            logger.error("Fout bij het openen of sluiten van de databaseconnectie tijdens het updaten van een gebruiker!");
            logger.error(ex.getMessage());
        }
        
        
        return gelukt;
    }
    
    public static ArrayList<Gebruiker> getOnlineGebruikers(){
        ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>();
        String opdracht = "{call selectOnlineGebruikers()}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            ResultSet rs = cstmt.executeQuery();
            while(rs.next()){
                Gebruiker g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
                
                gebruikers.add(g);
            }
            
            cstmt.close();
            logger.info("Online gebruikers succesvol opgehaald uit de database.");
        } catch (SQLException ex) {
            logger.error("Fout bij het ophalen van de lijst met online gebruikers!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return gebruikers;
    }
    
    public static ArrayList<Gebruiker> getOnlineNonGamingGebruikers(){
        ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>();
        String opdracht = "{call selectOnlineNonGamingGebruikers()}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            ResultSet rs = cstmt.executeQuery();
            while(rs.next()){
                Gebruiker g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
                
                gebruikers.add(g);
            }
            
            cstmt.close();
            logger.info("Online gebruikers succesvol opgehaald uit de database.");
        } catch (SQLException ex) {
            logger.error("Fout bij het ophalen van de lijst met online non-gaming gebruikers!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return gebruikers;
    }
    
    public static ArrayList<Gebruiker> getAlleGebruikers(){
        ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>();
        String opdracht = "{call selectGebruikers()}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            ResultSet rs = cstmt.executeQuery();
            while(rs.next()){
                Gebruiker g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
                
                gebruikers.add(g);
            }
            
            cstmt.close();
            logger.info("Alle gebruikers succesvol opgehaald uit de database.");
        } catch (SQLException ex) {
            logger.error("Fout bij het ophalen van de lijst met alle gebruikers!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return gebruikers;
    }
    
    public static Gebruiker getGebruikerByLogin(String nickname){
        Gebruiker g = null;
        String opdracht = "{call selectGebruikerByLogin(?)}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            cstmt.setString(1,nickname);
            
            logger.info("Gebruiker zoeken met nickname: " + nickname);
            
            ResultSet rs = cstmt.executeQuery();
            
            if(rs.next()){
                g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
            }
            
            if(g!=null){
                logger.info("Gebruiker " + nickname + " gevonden!");
            }else{
                logger.info("Gebruiker " + nickname + " niet gevonden!");
            }
            
            cstmt.close();
   
        } catch (SQLException ex) {
            logger.error("Fout bij het zoeken naar gebruiker!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return g;
    }
    
    public static boolean checkNicknameBestaatAl(String nickname){
        boolean bestaat = true;
        Gebruiker g = null;
        String opdracht = "{call checkNickname(?)}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            cstmt.setString(1,nickname);
            
            logger.info("Gebruiker zoeken met nickname: " + nickname);
            
            ResultSet rs = cstmt.executeQuery();
            
            if(rs.next()){
                g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
            }
            
            if(g!=null){
                logger.info("Gebruiker " + nickname + " gevonden!");
            }else{
                logger.info("Gebruiker " + nickname + " niet gevonden! bestaat op false gezet.");
                bestaat = false;
            }
            
            cstmt.close();
   
        } catch (SQLException ex) {
            logger.error("Fout bij het zoeken naar gebruiker!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return bestaat;
    }
    
    public static Gebruiker checkLoginGegevens(String nickname, String paswoord){
        Gebruiker g = null;
        String opdracht = "{call checkLogin(?,?)}";
        
        try {
            CallableStatement cstmt = Database.getInstance().getConnection().prepareCall(opdracht);
            cstmt.setString(1,nickname);
            cstmt.setString(2,paswoord);
            
            logger.info("Login check met nickname: " + nickname + " en paswoord: " + paswoord);
            
            ResultSet rs = cstmt.executeQuery();
            
            if(rs.next()){
                g = new Gebruiker();
                g.setNickname(rs.getString(bundle.getString("gebruiker_nickname")));
                g.setPaswoord(rs.getString(bundle.getString("gebruiker_paswoord")));
                g.setEmail(rs.getString(bundle.getString("gebruiker_email")));
                g.setGeboortedatum((Date)rs.getDate(bundle.getString("gebruiker_datum")));
                g.setGeslacht(rs.getString(bundle.getString("gebruiker_geslacht")));
                g.setHobbys(rs.getString(bundle.getString("gebruiker_hobbys")));
                g.setExtra(rs.getString(bundle.getString("gebruiker_extra")));
                g.setAvatar(rs.getString(bundle.getString("gebruiker_avatar")));
                g.setOnline(rs.getBoolean(bundle.getString("gebruiker_online")));
                g.setGaming(rs.getBoolean(bundle.getString("gebruiker_gaming")));
                g.setScoreId(rs.getInt(bundle.getString("gebruiker_score")));
            }
            
            if(g!=null){
                logger.info("Login check van gebruiker: " + nickname + " gelukt!");
            }else{
                logger.info("Login check van gebruiker: " + nickname + " mislukt!");
            }
   
            cstmt.close();
        } catch (SQLException ex) {
            logger.error("Fout bij het inloggen van de gebruiker!");
            logger.error(ex.getMessage());
        } finally{
            try {
                Database.getInstance().getConnection().close();
            } catch (SQLException ex) {
                logger.error("Fout bij het sluiten van de databaseconnectie!");
                logger.error(ex.getMessage());
            }
        }
        
        return g;
    }
    
    public static void main(String[] args){
        GebruikerDAO.getAlleGebruikers();
        
        Gebruiker g = GebruikerDAO.checkLoginGegevens("Hospital_Ghost","password");
        int i = 0;
        
        Gebruiker wim = new Gebruiker();
        wim.setNickname("Wim");
        wim.setPaswoord("password");
        wim.setEmail("wimduysburgh@gmail.com");
        wim.setAvatar("/hallo/wim.jpg");
        wim.setExtra("Extra Wim");
        wim.setHobbys("wim hobbys");
        wim.setGeboortedatum(new Date(System.currentTimeMillis()));
        wim.setGeslacht("M");
        wim.setScoreId(1);
        wim.setOnline(true);
        
        boolean gelukt = GebruikerDAO.updateGebruiker(wim);
    }
    
}
